﻿#include "common.h"

// FreeList

// 头插
void FreeList::push(void *obj)
{
    assert(obj);
    NextObj(obj) = m_freeList;
    m_freeList = obj;

    ++m_size;
}

// 头插n个对象
void FreeList::pushRange(void *start, void *end, size_t n)
{
    NextObj(end) = m_freeList;
    m_freeList = start;
    m_size += n;
}

// 头删n个对象
void FreeList::popRange(void *&start, void *&end, size_t n)
{
    assert(n <= m_size);
    start = m_freeList;
    end = start;

    for (size_t i = 0; i < n - 1; ++i)
    {
        end = NextObj(end);
    }

    m_freeList = NextObj(end);
    NextObj(end) = nullptr;
    m_size -= n;
}

// 头删
void *FreeList::pop()
{
    assert(m_freeList);
    void *obj = m_freeList;
    m_freeList = NextObj(obj);
    --m_size;

    return obj;
}

// 判空
bool FreeList::empty()
{
    return m_freeList == nullptr;
}

// 获取慢增长上限
size_t &FreeList::maxSize()
{
    return m_maxSize;
}

// 获取当前大小
size_t FreeList::size()
{
    return m_size;
}

//----------------------------------------------------------------------------------------
// SpanList
SpanList::SpanList()
{
    m_head = new Span;
    m_head->m_next = m_head;
    m_head->m_prev = m_head;
}

Span *SpanList::begin()
{
    return m_head->m_next;
}

Span *SpanList::end()
{
    return m_head;
}

bool SpanList::empty()
{
    return m_head->m_next == m_head;
}

void SpanList::pushFront(Span *span)
{
    insert(begin(), span);
}

Span *SpanList::popFront()
{
    Span *front = m_head->m_next;
    erase(front);
    return front;
}

void SpanList::insert(Span *pos, Span *newSpan)
{
    assert(pos);
    assert(newSpan);

    Span *prev = pos->m_prev;
    prev->m_next = newSpan;
    newSpan->m_prev = prev;
    newSpan->m_next = pos;
    pos->m_prev = newSpan;
}

void SpanList::erase(Span *pos)
{
    assert(pos);
    assert(pos != m_head);

    Span *prev = pos->m_prev;
    Span *next = pos->m_next;

    prev->m_next = next;
    next->m_prev = prev;
}

// 加锁
void SpanList::lock()
{
    m_mutex.lock();
}

// 解锁
void SpanList::unlock()
{
    m_mutex.unlock();
}

// ----------------------------------------------------------------------------------------

//SizeClass
